package com.xingkeduo.service.cms.marketing.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.xingkeduo.dao.TActivityDaysMapper;
import com.xingkeduo.dao.TActivityDaysMapperSpec;
import com.xingkeduo.dao.TMarketingCardMapper;
import com.xingkeduo.dao.TMarketingCouponBagMapper;
import com.xingkeduo.dao.TMarketingCouponMapper;
import com.xingkeduo.dao.TMarketingRelevantMapper;
import com.xingkeduo.dao.TMarketingRelevantMapperSpec;
import com.xingkeduo.model.example.TActivityDaysExample;
import com.xingkeduo.model.example.TMarketingRelevantExample;
import com.xingkeduo.model.param.ActivityDaysParam;
import com.xingkeduo.model.param.MarketingParam;
import com.xingkeduo.model.param.MarketingParam.MarketingServiceTypeEnum;
import com.xingkeduo.model.param.MarketingParam.MarketingStatusEnum;
import com.xingkeduo.model.param.MarketingParam.MarketingTypeEnum;
import com.xingkeduo.model.param.MarketingRelevantParam;
import com.xingkeduo.model.po.TActivityDays;
import com.xingkeduo.model.po.TMarketing;
import com.xingkeduo.model.po.TMarketingRelevant;
import com.xingkeduo.model.po.TMarketingWithBLOBs;
import com.xingkeduo.service.cms.marketing.InventoryService;
import com.xingkeduo.service.cms.marketing.MarketingTemplateService;
import com.xingkeduo.util.Constant;
import com.xingkeduo.util.tool.ResponseMessage;

@Service(value = "marketingTemplateService")
public class MarketingTemplateServiceImpl implements MarketingTemplateService {
	Logger logger = LoggerFactory.getLogger(MarketingTemplateServiceImpl.class);
	@Autowired
	TMarketingRelevantMapperSpec tMarketingRelevantMapperSpec;
	@Autowired
	TMarketingRelevantMapper tMarketingRelevantMapper;
	@Autowired
	InventoryService inventoryService;
	@Autowired
	TActivityDaysMapperSpec tActivityDaysMapperSpec;
	@Autowired
	TActivityDaysMapper tActivityDaysMapper;
	@Autowired
	@Qualifier(value = "marketingTemplateService")
	MarketingTemplateService marketingTemplateService;
	@Autowired
	TMarketingCouponMapper tMarketingCouponMapper;
	@Autowired
	TMarketingCardMapper tMarketingCardMapper;
	@Autowired
	TMarketingCouponBagMapper tMarketingCouponBagMapper;
	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
	public void addTMarketingRelevant(MarketingParam coupon) {
		MarketingTypeEnum marketingTypeEnum = MarketingTypeEnum.parseStatus(coupon.getMarketingType());
		switch (marketingTypeEnum) {
		case COUPON_BAG:
			// 新增券包下卡，券关联关系
			if (!CollectionUtils.isEmpty(coupon.getMarketingRelevantParams())) {
				tMarketingRelevantMapperSpec.insertByBatch(coupon);
			}
			// 库存验证
			checkCurrentInventory(coupon);
			// 新增库存变更记录
			for (MarketingRelevantParam marketingRelevantParam : coupon.getMarketingRelevantParams()) {
				String memo = "更新"+MarketingTypeEnum.parseStatus(Integer.parseInt(marketingRelevantParam.getMarketingType()))+"，新增优惠包变更库存";
				inventoryService.addInventoryModificationRecord(
						marketingRelevantParam.getSupportBusinessId().longValue(), coupon.getId(),
						marketingRelevantParam.getTotalQuantity().intValue() * coupon.getStockQuantity().intValue(),
						memo, coupon.getCreateBy(),Integer.parseInt(marketingRelevantParam.getMarketingType()));
			}
			break;
		default:
			// 新增券包下卡，券与发型服务关联关系
			if (MarketingServiceTypeEnum.FREQUENCY.getType().equalsIgnoreCase(coupon.getServiceType())
					&& (!CollectionUtils.isEmpty(coupon.getMarketingRelevantParams()))) {
				//本版本不考虑
				//tMarketingRelevantMapperSpec.insertByBatch(coupon);
			}
			// 新增券，卡活动时间
			if (!CollectionUtils.isEmpty(coupon.getActivityDaysParams())) {
				tActivityDaysMapperSpec.insertMarketingByBatch(coupon);
			}
			break;
		}
		// 新增库存变更记录
		inventoryService.addInventoryModificationRecord(coupon.getId(), coupon.getStockQuantity(),
							coupon.getCreateBy(),coupon.getMarketingType());

	}
	private TMarketing selectByPrimaryKey(Long supportBusinessId, String marketingType) {
		if(marketingType.equals(MarketingTypeEnum.COUPON.getCode()+"")) {
			return tMarketingCouponMapper.selectByPrimaryKey(supportBusinessId);
		}else if(marketingType.equals(MarketingTypeEnum.CARD.getCode()+"")) {
			return tMarketingCardMapper.selectByPrimaryKey(supportBusinessId);
		}else if(marketingType.equals(MarketingTypeEnum.COUPON_BAG.getCode()+"")) {
			return tMarketingCouponBagMapper.selectByPrimaryKey(supportBusinessId);
		}
		return null;
	}
	@Override
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
	public void updateTMarketingRelevant(TMarketingWithBLOBs oldTMarketingWith, MarketingParam coupon) {
		MarketingTypeEnum marketingTypeEnum = MarketingTypeEnum.parseStatus(coupon.getMarketingType());
		switch (marketingTypeEnum) {
		case COUPON_BAG:
			logger.info("【券卡关联数据】marketingRelevantParam:{}", JSON.toJSONString(coupon.getMarketingRelevantParams()));
			// 库存验证
			checkCurrentInventory(coupon);
			List<Long> marketIdList = new ArrayList<Long>();
			// 1新增，更新券包下卡，券关联关系
			for (MarketingRelevantParam marketingRelevantParam : coupon.getMarketingRelevantParams()) {
				// 1.1新增券，卡情况
				if (marketingRelevantParam.getId() == null) {
					TMarketing relevantMarketing = selectByPrimaryKey(marketingRelevantParam.getSupportBusinessId(),marketingRelevantParam.getMarketingType());
					// 1.1.1新增关联关系
					TMarketingRelevant tMarketingRelevant = new TMarketingRelevant(oldTMarketingWith.getId(),
							relevantMarketing.getMarketingType(), relevantMarketing.getId(),
							relevantMarketing.getName(), marketingRelevantParam.getTotalQuantity().intValue(),
							new Date(), new Date(), coupon.getServiceType(),Constant.STATUS_YES);
					tMarketingRelevantMapper.insertSelective(tMarketingRelevant);
					// 1.1.2新增库存变更记录
					String memo = "更新"+MarketingTypeEnum.parseStatus(Integer.parseInt(marketingRelevantParam.getMarketingType()))+",编辑(新增卡，券)优惠包变更库存";
					inventoryService.addInventoryModificationRecord(relevantMarketing.getId(),
							oldTMarketingWith.getId(), marketingRelevantParam.getTotalQuantity().intValue()
									* coupon.getSurplusQuantity().intValue(),
							memo, coupon.getCreateBy(),relevantMarketing.getMarketingType());
					marketIdList.add(tMarketingRelevant.getId());
				}
				// 1.2更新券，卡情况
				if (marketingRelevantParam.getId() != null) {
					// 1.2.1更新关联关系
					TMarketingRelevant tMarketingRelevant = tMarketingRelevantMapper
							.selectByPrimaryKey(marketingRelevantParam.getId());
					TMarketingRelevant newTMarketingRelevant = new TMarketingRelevant();
					BeanUtils.copyProperties(marketingRelevantParam, newTMarketingRelevant);
					// 1.2.2新增库存变更记录
					tMarketingRelevantMapper.updateByPrimaryKeySelective(newTMarketingRelevant);
					logger.info("库存 old:{},new:{},oldRel:{},newRel:{}",oldTMarketingWith.getStockQuantity(),coupon.getStockQuantity(),tMarketingRelevant.getTotalQuantity(),marketingRelevantParam.getTotalQuantity());
					if (oldTMarketingWith.getStockQuantity().intValue() != coupon.getStockQuantity().intValue() 
							|| tMarketingRelevant.getTotalQuantity().intValue() != marketingRelevantParam.getTotalQuantity()) {
						String memo = "更新"+MarketingTypeEnum.parseStatus(Integer.parseInt(marketingRelevantParam.getMarketingType()))+",编辑(修改卡，券)优惠包变更库存";
						inventoryService.addInventoryModificationRecord(
								marketingRelevantParam.getSupportBusinessId().longValue(), oldTMarketingWith.getId(),
								(marketingRelevantParam.getTotalQuantity().intValue()
										* coupon.getStockQuantity().intValue()
										- tMarketingRelevant.getTotalQuantity().intValue()
												* oldTMarketingWith.getStockQuantity().intValue()),
								memo, coupon.getCreateBy(),Integer.parseInt(marketingRelevantParam.getMarketingType()));
					}
					marketIdList.add(tMarketingRelevant.getId());
				}
			}
			// 2删除券包下卡，券关联关系
			if (!CollectionUtils.isEmpty(marketIdList)) {
				// 2.1新增库存更新记录
				TMarketingRelevantExample example = new TMarketingRelevantExample();
				example.createCriteria().andMarketingIdEqualTo(oldTMarketingWith.getId()).andIdNotIn(marketIdList).andStatusEqualTo(Constant.STATUS_YES);
				List<TMarketingRelevant> tMarketingRelevantList = tMarketingRelevantMapper.selectByExample(example);
				for (TMarketingRelevant tMarketingRelevant : tMarketingRelevantList) {
					if (oldTMarketingWith.getSurplusQuantity().intValue() > 0) {
						String memo = "更新"+MarketingTypeEnum.parseStatus(tMarketingRelevant.getMarketingType())+",编辑(删除卡，券)优惠包变更库存";
						inventoryService
								.addInventoryModificationRecord(tMarketingRelevant.getSupportBusinessId().longValue(),
										tMarketingRelevant.getMarketingId(),
										(0 - oldTMarketingWith.getSurplusQuantity().intValue())
												* tMarketingRelevant.getTotalQuantity().intValue(),
										memo, coupon.getCreateBy(),tMarketingRelevant.getMarketingType());
					}
				}
				// 2.2 删除关联关系
				TMarketingRelevant record = new TMarketingRelevant();
				record.setStatus(Constant.STATUS_NO_2);
				tMarketingRelevantMapper.updateByExampleSelective(record, example);
			}
			break;
		default:
			// 1 删除关联
			if (MarketingServiceTypeEnum.FREQUENCY.getType().equalsIgnoreCase(coupon.getServiceType()) // 卡-服务次卡
					|| (!coupon.getSupportServprodIds().equals(oldTMarketingWith.getSupportServprodIds()))) { // 其他券，卡服务ids不等
//				TMarketingRelevantExample tMarketingRelevantExample = new TMarketingRelevantExample();
//				tMarketingRelevantExample.createCriteria().andMarketingIdEqualTo(oldTMarketingWith.getId());
//				tMarketingRelevantMapper.deleteByExample(tMarketingRelevantExample);
//				// 2 重新匹配新关联
//				tMarketingRelevantMapperSpec.insertByBatch(coupon);
			}
			if(CollectionUtils.isEmpty(coupon.getActivityDaysParams())) {
				break;
			}
			List<Long> activityDaysList = new ArrayList<Long>();
			// 1 新增券，卡活动时间处理
			for (ActivityDaysParam activityDaysParam : coupon.getActivityDaysParams()) {
				// 1.1新增券，卡情况
				if (activityDaysParam.getId() == null) {
					// 1.1.1新增活动时间
					TActivityDays activityDays = new TActivityDays(oldTMarketingWith.getId(),
							oldTMarketingWith.getMarketingType(), activityDaysParam.getDayids(),
							activityDaysParam.getStartTime(), activityDaysParam.getEndTime(),
							activityDaysParam.getActivityAmount(), Constant.STATUS_YES, coupon.getCreateBy(),
							new Date(), coupon.getCreateBy(), new Date());
					tActivityDaysMapper.insertSelective(activityDays);
					activityDaysList.add(activityDays.getId());
				}
				// 1.2更新券，卡情况
				if (activityDaysParam.getId() != null) {
					// 1.2.1更新活动时间
					TActivityDays newTActivityDays = new TActivityDays();
					BeanUtils.copyProperties(activityDaysParam, newTActivityDays);
					tActivityDaysMapper.updateByPrimaryKeySelective(newTActivityDays);
					activityDaysList.add(activityDaysParam.getId());
				}
			}
			// 2 删除券包下卡，券 活动处理
			if (!CollectionUtils.isEmpty(activityDaysList)) {
				TActivityDays record = new TActivityDays();
				record.setStatus(Constant.STATUS_NO_2);
				TActivityDaysExample tActivityDaysExample = new TActivityDaysExample();
				tActivityDaysExample.createCriteria().andActivityTypeEqualTo(marketingTypeEnum.getCode())
						.andStatusEqualTo(Constant.STATUS_YES)
						.andActivityIdEqualTo(oldTMarketingWith.getId()).andIdNotIn(activityDaysList);
				tActivityDaysMapper.updateByExampleSelective(record,tActivityDaysExample);
			}
			break;
		}
		String memo = "更新" +marketingTypeEnum.getDesc()+ ",修改" +marketingTypeEnum.getDesc()+ "库存";
		inventoryService.addInventoryModificationRecord(oldTMarketingWith.getId(), oldTMarketingWith.getId(),
				(coupon.getStockQuantity().intValue() - oldTMarketingWith.getStockQuantity().intValue()), memo,
				coupon.getCreateBy(),oldTMarketingWith.getMarketingType());
	}
	
	
	private void checkCurrentInventory(MarketingParam coupon) {
		for (MarketingRelevantParam marketingRelevantParam : coupon.getMarketingRelevantParams()) {
			TMarketing marketing = selectByPrimaryKey(marketingRelevantParam.getSupportBusinessId(),marketingRelevantParam.getMarketingType());
			if (marketing == null) {
				throw new RuntimeException("查询无数据，id:" + marketingRelevantParam.getSupportBusinessId() + ",名称:"
						+ marketingRelevantParam.getServprodName());
			}
			if (marketing.getMarketingType() != MarketingTypeEnum.COUPON.getCode()
					&& marketing.getMarketingType() != MarketingTypeEnum.CARD.getCode()) {
				throw new RuntimeException("优惠包下只能包含券和卡");
			}
			if (marketing.getStockQuantity().intValue() == 0) {
				continue;
			}
			String marketType = "券";
			if (marketing.getMarketingType().intValue() == MarketingTypeEnum.CARD.getCode()) {
				marketType = "卡";
			}
			if (MarketingStatusEnum.UP.getCode() != marketing.getStatus()) {
				throw new RuntimeException(marketType+"未上架 id:" + marketingRelevantParam.getSupportBusinessId() + ",名称:"
						+ marketingRelevantParam.getServprodName());
			}
			if(marketingRelevantParam.getTotalQuantity()==null || marketingRelevantParam.getTotalQuantity().intValue()<=0) {
				throw new RuntimeException(
						marketType+"id:" + marketing.getId() + ",名称:" + marketing.getName()+",设置的数量必须大于0");
			}
			if (marketingRelevantParam.getId() == null) {
				if (marketing.getSurplusQuantity().intValue() - marketingRelevantParam.getTotalQuantity().intValue()
						* coupon.getStockQuantity().intValue() < 0) {
					throw new RuntimeException("库存不足，" + marketType + "id:" + marketing.getId() + ",名称:" + marketing.getName()+ ",库存:"
							+ marketing.getSurplusQuantity());
				}
			}
			if (marketingRelevantParam.getId() != null) {
				TMarketingRelevant tMarketingRelevant = tMarketingRelevantMapper
						.selectByPrimaryKey(marketingRelevantParam.getId());
				if (tMarketingRelevant.getTotalQuantity().intValue() < marketingRelevantParam.getTotalQuantity()
						.intValue()) {
					if (marketing.getSurplusQuantity().intValue()
							- (marketingRelevantParam.getTotalQuantity().intValue()
									- tMarketingRelevant.getTotalQuantity().intValue())
									* coupon.getStockQuantity().intValue() < 0) {
						throw new RuntimeException("库存不足，" + marketType + "id:" + marketing.getId() + ",名称:" + marketing.getName()+ ",库存:"
								+ marketing.getSurplusQuantity());
					}
				}
			}
		}
	}
	@Override
	public ResponseMessage saveOrUpdateCouponByTemplate(MarketingParam couponTemplate) {
		return null;
	}
	@Override
	public ResponseMessage queryCouponById(Long couponTemplateId) {
		return null;
	}
	@Override
	public ResponseMessage queryCouponByTemplate(MarketingParam couponTemplateExample) {
		return null;
	}
	@Override
	public ResponseMessage updateCouponStatusById(MarketingParam couponTemplate) {
		return null;
	}
	@Override
	public ResponseMessage getAllCouponTemplateList(MarketingParam couponTemplateExample) {
		return null;
	}
}
